package com.wn.common.db.dao

import androidx.lifecycle.LiveData
import androidx.room.*
import com.wn.common.constant.TABLE_VIDEO_LIST
import com.wn.common.db.entity.VideoInfo
import kotlinx.coroutines.flow.Flow

/**
 * @Author: wn
 * @Date: 2024/12/3 16:04
 * @Description: 数据操作的方法DO
 * 多个 Entity 需要多个 Dao
 * 1. OnConflictStrategy.REPLACE：冲突策略是覆盖旧数据同时继续事务。
 * 2. OnConflictStrategy.ROLLBACK：冲突策略是回滚事务。
 * 3. OnConflictStrategy.ABORT：冲突策略是终止事务。===========默认
 * 4. OnConflictStrategy.FAIL：冲突策略是事务失败。
 * 5. OnConflictStrategy.IGNORE：冲突策略是忽略冲突。
 */
@Dao
interface VideoListCacheDao {
  // 这条VideoInfo对象新的数据，id已经存在了这个表当中，此时就会发生冲突,覆盖掉
  @Insert(entity = VideoInfo::class, onConflict = OnConflictStrategy.REPLACE)
  suspend fun insert(videoInfo: VideoInfo)

  /**
   * 插入多个数据
   */
  @Insert(onConflict = OnConflictStrategy.REPLACE)
  suspend fun insertAll(videoList: MutableList<VideoInfo>)

  /**
   * 根据id删除数据
   */
  @Query("DELETE FROM $TABLE_VIDEO_LIST WHERE id = :id")
  fun deleteById(id: Long)

  /**
   * 删除指定item
   * 使用主键将传递的实体实例与数据库中的行进行匹配。如果没有具有相同主键的行，则不会进行任何更改
   */
  @Delete
  fun delete(videoInfo: VideoInfo): Int

  /**
   * 删除表中所有数据
   */
  @Query("DELETE FROM $TABLE_VIDEO_LIST")
  suspend fun deleteAll()

  /**
   * 更新某个item
   * 不指定的entity也可以，会根据你传入的参数对象来找到你要操作的那张表
   */
  @Update
  suspend fun update(videoInfo: VideoInfo): Int

  /**
   * 根据id更新数据
   */
  @Query("UPDATE $TABLE_VIDEO_LIST SET title=:title WHERE id=:id")
  suspend fun updateById(id: Long, title: String)

  /**
   * 查询所有数据
   */
  @Query("SELECT * FROM $TABLE_VIDEO_LIST")
  fun queryAll(): MutableList<VideoInfo>?

  /**
   * 根据id查询某个数据
   */
  @Query("SELECT * FROM $TABLE_VIDEO_LIST WHERE id=:id")
  fun query(id: Long): Flow<VideoInfo?>

  /**
   * 通过LiveData以观察者的形式获取数据库数据，可以避免不必要的NPE，
   * 可以监听数据库表中的数据的变化，也可以和RXJava的Observer使用
   * 一旦发生了insert，update，delete，room会自动读取表中最新的数据，发送给UI层，刷新页面
   * 不要使用MutableLiveData和suspend 会报错
   */
  @Query("SELECT * FROM $TABLE_VIDEO_LIST")
  fun queryAllLiveData(): LiveData<List<VideoInfo>>
}